﻿#include "mainwidget.h"
#include "ui_mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);
    //禁止窗口改变大小
    this->setFixedSize(this->geometry().size());
    //隐藏标题栏
    this->setWindowFlag(Qt::FramelessWindowHint);

    //1.判断数据库是否存在，存在就得到连接，如果不存在添加得到连接
    if(QSqlDatabase::contains("sql_default_connection"))
    {
        //根据数据库默认连接名称得到连接
        db=QSqlDatabase::database("sql_default_connection");
    }else {
        db=QSqlDatabase::addDatabase("QSQLITE");//添加QSQLITE数据库
        db.setDatabaseName("mp3listdatabase.db");//设置数据库的名字
    }
    //2.打开数据库，打开标识(QsqlQuery)类
    if(!db.open())
    {
        QMessageBox::critical(0,QObject::tr("open Data error"),db.lastError().text());
    }else {
        //3.定义query对象,得到打开的数据库标识
        QSqlQuery query;
        QString sql="create table if not exists searchlist(id integer primary key, musicid integer,mucsicName text,singerName text,musicDuration text,albumName text);";
        if(!query.exec(sql))
        {
            QMessageBox::critical(0,QObject::tr("create searchlist error"),db.lastError().text());
        }
        //歌曲痕迹数据表
        sql="create table if not exists historysong(id integer primary key autoincrement, musicid integer,mucsicName text,singerName text,musicDuration text,albumName text);";
        if(!query.exec(sql))
        {
            QMessageBox::critical(0,QObject::tr("create historysong error"),db.lastError().text());
        }
        //查询历史数据表中插入歌曲数据
        sql="select * from historysong;";
        if(!query.exec(sql))
        {
            QMessageBox::critical(0,QObject::tr("select historysong error"),db.lastError().text());
        }
        while (query.next()) {
            //将歌名和歌手显示到布局中
            QString songname,singername;
            QSqlRecord rec=query.record();
            int alumkey=rec.indexOf("mucsicName");
            int hashKey=rec.indexOf("singerName");
            songname=query.value(alumkey).toString();
            singername=query.value(hashKey).toString();
            QString strshow=songname+"--"+singername;
            QListWidgetItem *item=new QListWidgetItem(strshow);
            ui->listWidget_History->addItem(item);
        }
    }
    //播放操作
    player=new QMediaPlayer;
   // playerlist=new QMediaPlaylist;后面处理
    connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(updateDuration(qint64)));
    connect(this,SIGNAL(lyricShow(string)),this,SLOT(lyricTextShow(QString)));

    connect(ui->listWidget_Search,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(playSearchMusic()));
    connect(ui->listWidget_History,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(playHistoryMusic()));
    //更换软件皮肤的菜单项
    QAction *actionbackgroundtoDefault=new QAction(QIcon(":/new/prefix1/mp3/beijing1.jpg"),u8"Default");
    connect(actionbackgroundtoDefault,SIGNAL(triggered(bool)),this,SLOT(backgroundtodefault()));

    QAction *actionbackgroundtoSetting=new QAction(QIcon(":/new/prefix1/mp3/bieji2.jpg"),u8"Custom");
    connect(actionbackgroundtoSetting,SIGNAL(triggered(bool)),this,SLOT(backgroundtoSetting()));
    menuchangeSkin=new QMenu(this);
    menuchangeSkin->addAction(actionbackgroundtoDefault);
    menuchangeSkin->addAction(actionbackgroundtoSetting);
    backgroundtodefault();
}

MainWidget::~MainWidget()
{
    delete ui;
}
void MainWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.drawPixmap(0,0,this->width(),this->height(),QPixmap(":/new/prefix1/mp3/beij.png"));
}
void MainWidget::on_pushButton_Close_clicked()
{
    //关闭窗口
    close();
}


void MainWidget::on_pushButton_Skin_clicked()//更换皮肤
{
    menuchangeSkin->exec(QCursor::pos());//在当前鼠标的位置弹出名为menuChangeSkin的菜单

}


void MainWidget::on_pushButton_About_clicked()
{
    QMessageBox::about(this,tr("mmy的音乐播放器"),"2024/3/23音乐播放器Qt项目,作者:社会加班人\n"
                                                    "功能入界面所示，但会存在一定的bug,xxxxx");
}


void MainWidget::on_pushButton_Seacrch_clicked()//搜索音乐
{
   //将原有歌曲数据清空
    ui->listWidget_Search->clear();
   //清理数据库中存在的hash资源
    QSqlQuery query;
    QString sql="delete from searchlist;";
    if(!query.exec(sql))
    {
        QMessageBox::critical(0,QObject::tr("delete searchlist error"),db.lastError().text());
    }
    //在根据用户输入的MP3音乐名称，发起请求                //page=1表示页码为1页,pagesize=20表示每页显示的20项
    QString url=kugouSearchApi+QString("csrf_token=hlpretag=&hlposttag=&s=%1&type=1&offset=0&total=true&limit=2").arg(ui->lineEdit_Search->text());
    httpAccess(url);
    QByteArray JsonData;
    QEventLoop loop;
    auto c=connect(this,finish,[&](const QByteArray &data)
    {
        JsonData=data;
        loop.exit(1);//退出事件循环
    });
    loop.exec();//循环开始
    disconnect(c);
    //解析网页回复的数据，将搜索得到的音乐hash,album_id与列表的索引值存放到数据库
    hashJsonAnalysis(JsonData);
}


void MainWidget::on_VopSlider_valueChanged(int value)//声音大小的设置
{
    audioOutput->setVolume(value);
    ui->label_Vop->setText(QString::number(value));
}

void MainWidget::on_progressSlider_valueChanged(int value)//音乐进度条
{
    QTime time(0,value/60000,qRound((value%60000)/1000.0));
    ui->label_Time->setText(time.toString("mm:ss"));
    if(i==false)
    {
        player->setPosition(qint64(value));
        update();
    }
}


void MainWidget::on_progressSlider_sliderPressed()//音乐进度条按下拖动
{
    i=false;
}


void MainWidget::on_progressSlider_sliderReleased()//音乐进度条按下释放
{
    i=true;
}


void MainWidget::on_pushButton_Front_clicked() //上一曲
{
    row--;
    if(row<0)
    {
        row=ui->listWidget_History->count();
    }
    QSqlQuery query;
    QString sql=QString("select * from historysong where id=%1;").arg(row+1);
    if(!query.exec(sql))
    {
        QMessageBox::critical(0,QObject::tr("select historysong error"),db.lastError().text());
    }
    int musicid;
    if(query.next()){
        QSqlRecord recd=query.record();
        int musickey=recd.indexOf("musicid");
        musicid=query.value(musickey).toInt();
    }
    downloadPlayer(musicid);
}


void MainWidget::on_pushButton_Playpause_clicked()//暂停
{
    if(bofang==false)
    {
        player->pause();
        ui->pushButton_Playpause->setIcon(QIcon(":/new/prefix1/mp3/stop.jpg"));
        bofang=true;
        update();
    } else {
        player->play();
        ui->pushButton_Playpause->setIcon(QIcon(":/new/prefix1/mp3/bofang.jpg"));
        bofang=false;
        update();
    }
}


void MainWidget::on_pushButton_Next_clicked()//下一曲
{
    row++;
    if(row>ui->listWidget_History->count())
    {
        row=0;
    }
    QSqlQuery query;
    QString sql=QString("select * from historysong where id=%1;").arg(row+1);
    if(!query.exec(sql))
    {
        QMessageBox::critical(0,QObject::tr("select historysong error"),db.lastError().text());
    }
    int musicid;
    if(query.next()){
        QSqlRecord recd=query.record();
        int musickey=recd.indexOf("musicid");
        musicid=query.value(musickey).toInt();
    }
    downloadPlayer(musicid);
}

void MainWidget::on_pushButton_Loop_clicked()//循环播放
{
    if(loop==true)
    {
        loop=false;
        ui->pushButton_Loop->setText("取消循环");
        player->setLoops(-1);
    }else {
        player->setLoops(1);
        ui->pushButton_Loop->setText("循环播放");
    }

}
//更新播放的进度条和显示时间
void MainWidget::updateDuration(qint64 value)
{
    ui->progressSlider->setRange(0,player->duration());
    ui->progressSlider->setValue(value);
}
//读取网络数据的槽函数
void MainWidget::netReply(QNetworkReply *reply)
{
  //获取响应信息,状态码为200属于正常
    QVariant status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    qDebug()<<status_code;
    reply->attribute(QNetworkRequest::RedirectionTargetAttribute);//重定向,允许服务器将客户端的请求指向另一个资源或地址
    //没有错误返回
    if(reply->error()==QNetworkReply::NoError)
    {
        QByteArray data=reply->readAll();
        emit finish(data);
    } else {
        qDebug()<<reply->errorString();
    }
    reply->deleteLater();//延迟删除对象
}
//显示歌词的槽函数
void MainWidget::lyricTextShow(QString lycris)
{
    ui->textEdit_Lyric->setFont(QFont("宋体",10,QFont::Bold));
    ui->textEdit_Lyric->setTextColor(Qt::white);
    ui->textEdit_Lyric->setText(lycris);
}
//音乐歌曲的下载和播放
void MainWidget::downloadPlayer(int musicId)
{

    QString url=kugouDownloadApi+QString("id=%1").arg(musicId);
    QString lycir=QString("https://music.163.com/api/song/lyric?id=%1&lv=1&kv=1&tv=-1").arg(musicId);
    // qDebug()<<url;
    httpAccess(lycir);
    QByteArray JsonData;
    QEventLoop loop;
    auto d=connect(this,finish,[&](const QByteArray &data)
    {
        JsonData=data;
        loop.exit(1);
    });
    loop.exec();
    disconnect(d);

    //解析将要播放音乐的歌词
    musicJsonAnalysis(JsonData);
   // qDebug()<<music;
    //player->setMedia(QUrl(music));//qt6已经废除了
    player->setSource(QUrl(url));
    //设置音量
    //player->setVolume(60);//qt6已经废除了
    // 获取音频输出设备
    audioOutput=new QAudioOutput;
    // 设置音量
    player->setAudioOutput(audioOutput);
    audioOutput->setVolume(60);
    //设置音量播放条
    ui->VopSlider->setValue(60);
    //播放音乐
    player->play();
}
//访问HTTP网页
void MainWidget::httpAccess(QString url)
{
    //实例化网络请求操作事项
    request=new QNetworkRequest;
    //将url网页存在request请求当中
    request->setUrl(url);
    //实例化网络管理(访问)
    manager=new QNetworkAccessManager;
    //使用get方法，上传具体的请求
    manager->get(*request);
   //当网页回复消息时，触发finished信号,然后读取数据信息
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(netReply(QNetworkReply*)));
}
//音乐的hash和album_id值的解析，使用JSON
//音乐的id和album id值的解析使用JSON
void MainWidget::hashJsonAnalysis(QByteArray JsonData)
{
    QJsonParseError err;               //错误信息对象
    QJsonDocument json_recv = QJsonDocument::fromJson(JsonData,&err);//将json文本转换为 json 文件对象
    if(err.error != QJsonParseError::NoError)             //判断是否符合语法
    {
        qDebug() <<"搜索歌曲Json获取格式错误"<< err.errorString();
        return;
    }
    QJsonObject totalObject = json_recv.object();
    QStringList keys = totalObject.keys();    // 列出json里所有的key
    if(keys.contains("result"))                 //如果有结果
    {       //在 json 文本中 {}花括号里面是QJsonObject对象, []方括号里面是QJsonArray

        QJsonObject resultObject = totalObject["result"].toObject();     //就将带 result 的内容提取后转换为对象
        QStringList resultKeys = resultObject.keys();      //保存所有key
        if(resultKeys.contains("songs"))                    //如果 key 为songs ,代表找到了歌曲
        {

            QJsonArray array = resultObject["songs"].toArray();
            for(int i=0;i< array.count();i++)                   //开始获取歌曲中的信息
            {

                QJsonObject object = array.at(i).toObject();
                musicId = object["id"].toInt();                         // 音乐id
                musicDuration = object["duration"].toInt();             // 音乐长度
                musicName = object["name"].toString();                  // 音乐名
                mvId = object["mvid"].toInt();                          // mvid
                QStringList artistsKeys = object.keys();
                if(artistsKeys.contains("artists"))                //如果result中包含了 artists
                {
                    QJsonArray artistsArray = object["artists"].toArray();   //将 artist 的内容提取后保存
                    for(auto j : artistsArray)
                    {
                        QJsonObject object2 = j.toObject();
                        singerName = object2["name"].toString();         // 歌手名
                    }
                }
                if(artistsKeys.contains("album"))                //包含了专辑
                {
                    QJsonObject albumObjct = object["album"].toObject();
                    albumName = albumObjct["name"].toString();            // 专辑名
                }
                //将解析的JSON文件加入到数据库中
                QSqlQuery query;
                QString sql=QString("insert into searchlist (musicid,mucsicName,singerName,musicDuration,albumName) values(%1,'%2','%3','%4','%5')").arg(QString::number(musicId)).arg(musicName).arg(singerName).arg(QString::number(musicDuration)).arg(albumName);
                if(!query.exec(sql))
                {
                    QMessageBox::critical(0,QObject::tr("insert searchlist error"),db.lastError().text());
                }
                //将解析的音乐名称,存入到listwidget_Search控件列表进行显示
                QString show=musicName+"--"+singerName;
                QListWidgetItem *item=new QListWidgetItem(show);
                ui->listWidget_Search->addItem(item);
            }
        }
    }
}
//搜索的音乐数据信息JSON解析，解析出真正的音乐文件和歌词
QString MainWidget::musicJsonAnalysis(QByteArray JsonData)
{
    QJsonDocument document=QJsonDocument::fromJson(JsonData);
    if(document.isObject())
    {
       QJsonObject jsonObject = document.object();
        QJsonObject lrcObj = jsonObject["lrc"].toObject();
        int lrcVersion = lrcObj["version"].toInt();
        QString lrcLyric = lrcObj["lyric"].toString();
        qDebug()<<lrcLyric;
        lyricTextShow(lrcLyric);
    }
    if(document.isArray())
    {
        qDebug()<<"Array.";
    }
    return 0;
}
void MainWidget::playSearchMusic()//双击搜索列表，
{
    //播放音乐musicid integer,mucsicName text,singerName text,musicDuration text,albumName text
    //musicid integer,mucsicName text,singerName text,musicDuration text,albumName text
    //获取双击的歌曲对应索引
    int row=ui->listWidget_Search->currentRow();
    //从数据库中查询音乐的信息
    QSqlQuery query;
    QString sql=QString("select * from searchlist where id=%1;").arg(row+1);
    if(!query.exec(sql))
    {
        QMessageBox::critical(0,QObject::tr("select seachlist table Error."),db.lastError().text());
    }
    //将选中的音乐的数据包信息存入到历史数据表中
    QString mucsicName,singerName,albumName;
    int musicid,musicDuration;
    if (query.next()){
        QSqlRecord recd=query.record();
        int musickey=recd.indexOf("musicid");
        int mucsicNamekey=recd.indexOf("mucsicName");
        int singerNamekey=recd.indexOf("singerName");
        int musicDurationkey=recd.indexOf("musicDuration");
        int albumNamekey=recd.indexOf("albumName");
        musicid=query.value(musickey).toInt();
        qDebug()<<musicid;
        mucsicName=query.value(mucsicNamekey).toString();
        singerName=query.value(singerNamekey).toString();
        musicDuration=query.value(musicDurationkey).toInt();
        albumName=query.value(albumNamekey).toString();
        sql=QString("select musicid from historysong where musicid='%1';").arg(musicid);

        if(!query.exec(sql))
        {
            QMessageBox::critical(0,QObject::tr("select hash table Error."),db.lastError().text());
        }
        if(query.next()==NULL)
        {
            sql=QString("insert into historysong values(NULL,%2,'%3','%4',%5,'%6')").arg(musicid).arg(musicName).arg(singerName).arg(musicDuration).arg(albumName);
            if(!query.exec(sql))
            {
                QMessageBox::critical(0,QObject::tr("insert into historysong Error."),db.lastError().text());
            }
            //将音乐名称，保存到listwidget_history列表控件中
            QString show=musicName+"--"+singerName;
            QListWidgetItem *item=new QListWidgetItem(show);
            ui->listWidget_History->addItem(item);
        }
    downloadPlayer(musicid);
    }
}
void MainWidget::playHistoryMusic()//双击历史播放列表，播放音乐
{
    int row=ui->listWidget_History->currentRow();
    //从数据库中查询音乐的信息
    QSqlQuery query;
    QString sql=QString("select * from historysong where id=%1;").arg(row+1);
    qDebug()<<sql;
    if(!query.exec(sql))
    {
        QMessageBox::critical(0,QObject::tr("select seachlist table Error."),db.lastError().text());
    }
    //将选中的音乐的数据包信息存入到历史数据表中
    int musicid;
    if(query.next()){
        QSqlRecord recd=query.record();
        int musickey=recd.indexOf("musicid");
        musicid=query.value(musickey).toInt();
        qDebug()<<1;
    }
    downloadPlayer(musicid);
}
void MainWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(mousePress)
    {
        QPoint movepos=event->globalPos();
        move(movepos-movePoint);
    }
}
void MainWidget::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);//“不要警告我未使用的变量 event”
    mousePress=false;
}
void MainWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        mousePress=true;
    }
    movePoint=event->globalPos()-pos();

}
//更换皮肤的槽函数
void MainWidget::backgroundtodefault()//更换到默认背景皮肤
{
//获取widget的palette
    QPalette palette=this->palette();
    palette.setBrush(QPalette::Window,QBrush(QPixmap(":/new/prefix1/mp3/beijing1.jpg").scaled(this->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)));

    this->setPalette(palette);
}
void MainWidget::backgroundtoSetting()//更换自定义皮肤
{
    QString strFileName=QFileDialog::getOpenFileName(this,"请选择自定义背景图",QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).first(),u8"*.jpg *.png");
    QPalette palette=this->palette();
    palette.setBrush(QPalette::Window,QBrush(QPixmap(strFileName).scaled(this->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)));
    this->setPalette(palette);
}
